<template>
  <div class="fc-style">
    <a-layout class="fc-container">
      <a-layout-content class="fc-main">
        <a-layout>
          <a-layout-sider theme="light" :width="250">
            <div class="components">
              <ComponentGroup title="输入型字段" :fields="props.basicFields" :list="antd.basicComponents" />
              <ComponentGroup title="选择型字段" :fields="selectFields" :list="antd.selectComponents" />
              <div :style="{ padding: '8px 12px' }">
                <a-button type="primary" ghost :block="true" @click="addField">选择业务字段</a-button>
              </div>
            </div>
          </a-layout-sider>
          <a-layout class="center-container">
            <AntdHeader
              :only-submit="onlySubmit"
              :is-modal="isModal"
              @preview="() => (state.previewVisible = true)"
              @upload-json="() => (state.uploadJsonVisible = true)"
              @submit="handleSave"
            >
              <slot name="header"></slot>
            </AntdHeader>
            <a-layout-content :class="{ 'widget-empty': state.widgetForm.list }">
              <AntdWidgetForm
                ref="widgetFormRef"
                v-model:widgetForm="state.widgetForm"
                v-model:widgetFormSelect="state.widgetFormSelect"
                @itemClick="itemClick"
              />
            </a-layout-content>
          </a-layout>
          <a-layout-sider theme="light" class="widget-config-container" :width="300">
            <a-layout>
              <a-layout-header>
                <div
                  class="config-tab"
                  :class="{ active: state.configTab === 'widget' }"
                  @click="state.configTab = 'widget'"
                >
                  字段属性
                </div>
                <div
                  class="config-tab"
                  :class="{ active: state.configTab === 'form' }"
                  @click="state.configTab = 'form'"
                >
                  表单属性
                </div>
              </a-layout-header>
              <a-layout-content class="config-content">
                <AntdWidgetConfig
                  v-show="state.configTab === 'widget'"
                  key="widget"
                  v-model:select="state.widgetFormSelect"
                  :form-business-level="formBusinessLevel"
                  :all-data="state.widgetForm"
                />
                <AntdFormConfig
                  v-show="state.configTab === 'form'"
                  ref="refAntdFormConfig"
                  key="form"
                  v-model:config="state.widgetForm.config"
                />
              </a-layout-content>
            </a-layout>
          </a-layout-sider>
        </a-layout>
      </a-layout-content>

      <chooseField ref="chooseFieldRef" @submit="convertFieldListToShow" />
    </a-layout>
  </div>
</template>

<script setup lang="ts" name="AntdDesignForm">
import { reactive, ref, onMounted, computed, provide, nextTick } from 'vue'
import ComponentGroup from './components/ComponentGroup.vue'
import AntdHeader from './AntdHeader.vue'
import AntdWidgetForm from './AntdWidgetForm.vue'
import AntdWidgetConfig from './AntdWidgetConfig.vue'
import AntdFormConfig from './AntdFormConfig.vue'
import { antd, attrs, getVal, setVal, defaultLabels } from '../config'
import { CodeType } from '../enums'
import { cloneDeep } from 'lodash'
import chooseField from './components/chooseField.vue'
import { fieldTypeOpstion, fieldType } from '@@/enums/customFormEnums'
import { formAdd, formDetail, formUpdate, formDetailApp, formUpdateApp, formAddApp } from '@@/api/form/index'
import { getDatePickerFormat } from '../config'
import dayjs from 'dayjs'

const emits = defineEmits(['afterSubmit'])

const props = withDefaults(
  defineProps<{
    preview: boolean
    generateJson: boolean
    generateCode: boolean
    clearable: boolean
    uploadJson: boolean
    basicFields: Array<string>
    selectFields: Array<string>
    layoutFields: Array<string>
    // 是否新增
    isAdd: boolean
    // 表单主键
    formId: string
    // 表单层级
    formBusinessLevel: number
    // 表单归属业务主键
    belongBusinessId: string
    // 是否模态框
    isModal: boolean
  }>(),
  {
    preview: true,
    generateCode: true,
    generateJson: true,
    uploadJson: true,
    clearable: true,
    basicFields: () => ['input', 'password', 'textarea', 'number', 'rate', 'switch', 'slider', 'text'],
    selectFields: () => ['radio', 'checkbox', 'time', 'date', 'select', 'upload', 'cascader'],
    layoutFields: () => ['grid'],
    isAdd: true,
    formId: '',
    formBusinessLevel: 0,
    belongBusinessId: '0',
    isModal: false
  }
)
const state = reactive({
  antd,
  codeType: CodeType,
  widgetForm: cloneDeep(antd.widgetForm),
  widgetFormSelect: undefined,
  configTab: 'form',
  previewVisible: false,
  uploadJsonVisible: false,
  dataJsonVisible: false,
  dataCodeVisible: false,
  generateJsonVisible: false,
  generateCodeVisible: false,
  generateJsonTemplate: JSON.stringify(antd.widgetForm, null, 2),
  dataJsonTemplate: '',
  dataCodeTemplate: '',
  codeLanguage: CodeType.Vue,
  jsonEg: JSON.stringify(antd.widgetForm, null, 2)
})

// const generateFormRef = ref()

const chooseFieldRef = ref()

// const mainProps = ['fieldName', 'key', 'fieldId', 'fieldType', 'fieldCode', 'model', 'type', 'options']

// const optionsProps = [
//   'defaultValue',
//   'promptInfo',
//   'hidePromptFlag',
//   'showDivider',
//   'placeholder',
//   'attr',
//   'remote',
//   'remoteFunc',
//   'props',
//   'dateType',
//   'format',
//   'showLabel',
//   'format',
//   'maxlength',
//   'min',
//   'max',
//   'decimalPoint',
//   'multiple',
//   'visibleFlag',
//   'readonlyFlag',
//   'gridLayoutNumber'
// ]

// const rules = ['trigger', 'enum', 'whitespace', 'len', 'max', 'message', 'min', 'pattern', 'required', 'type']

// const handleUploadJson = () => {
//   try {
//     setJson(JSON.parse(state.jsonEg))
//     state.uploadJsonVisible = false
//     message.success('上传成功')
//   } catch (error) {
//     message.error('上传失败')
//   }
// }

// const handleCopyClick = (text: string) => {
//   copy(text)
//   message.success('Copy成功')
// }
const refAntdFormConfig = ref()
onMounted(() => {
  if (props.isAdd) {
    return
  }
  const fn = props.formBusinessLevel < 4 ? formDetail : formDetailApp
  fn({ formId: props.formId }).then((res: any) => {
    const tempConfig = cloneDeep(res)
    delete tempConfig.fieldList
    state.widgetForm.config = {
      ...tempConfig
    }
    nextTick(() => {
      refAntdFormConfig.value?.getFormTypeList()
    })
    convertFieldListToShow(res.fieldList)
  })
})

// 获取表单填写数据
// const handleGetData = () => {
//   generateFormRef.value.getData(false).then((res: any) => {
//     state.dataJsonTemplate = JSON.stringify(res, null, 2)
//     state.dataJsonVisible = true
//   })
// }

// watchEffect(() => {
//   if (state.dataCodeVisible) {
//     state.dataCodeTemplate = generateCode(state.widgetForm, state.codeLanguage, PlatformType.Antd)!
//   }
// })

// 重置表单数据
// const handleReset = () => generateFormRef.value.reset()

const itemClick = () => {
  if (state.configTab === 'form') {
    state.configTab = 'widget'
  }
}

/**
 * 保存设计数据
 */
const repeatFieldIds = ref<string[]>([])
provide('repeatFieldIds', repeatFieldIds)
const handleSave = (formStatus) => {
  repeatFieldIds.value = []
  const { config, list, deleteFieldIds } = state.widgetForm
  const formData: any = {
    formBusinessLevel: props.formBusinessLevel,
    belongBusinessId: props.belongBusinessId,
    formStatus: formStatus, // 1: 启用 0: 停用
    formName: config.formName,
    formType: config.formType,
    projectType: config.projectType,
    formDesc: config.formDesc,
    appId: config.appId,
    fieldList: [],
    deleteFieldIds
  }
  list.forEach((item) => {
    const temp: any = {}
    attrs.forEach((attr) => {
      let value = getVal(item, attr.local)
      if (attr.remote === 'requiredFlag') {
        // 因为rules里面的requered是一个布尔类型，所以要转换一下
        value = value ? 1 : 0
      } else if (attr.remote === 'defaultVal') {
        value = convertDefaultValToSubmit(item)
      } else if (attr.remote === 'fieldId') {
        if (isNaN(value)) {
          // 如果是fieldId是uuid，则默认为新增的自定义字段，不需要传fieldId字段
          return
        }
      } else if (attr.remote === 'remoteConfig') {
        if ([fieldType.select, fieldType.cascader].includes(item.fieldType) && item.options.remote === 2) {
          // 下拉框类型字段与级联类型字段且选项来源是远端数据不做处理
        } else {
          return
        }
      }
      temp[attr.remote] = value
    })
    formData.fieldList.push(temp)
  })
  let fn = formAdd
  if (props.isAdd) {
    fn = props.formBusinessLevel < 4 ? formAdd : formAddApp
    formData.belongDomainId = props.formBusinessLevel < 4 ? null : sessionStorage.getItem('__projectId')
  } else {
    fn = props.formBusinessLevel < 4 ? formUpdate : formUpdateApp
    formData.formId = props.formId
    formData.revision = config.revision
  }
  fn(formData)
    .then(() => {
      emits('afterSubmit')
    })
    .catch((res) => {
      if (res.code === 'I09002') {
        repeatFieldIds.value = res.data
      }
    })
}

/**
 * 转换默认值格式
 */
const convertDefaultValToSubmit = (localField) => {
  if ([fieldType.singleLineText, fieldType.multiLineText, fieldType.dateTime].includes(localField.fieldType)) {
    // 字符串
    if (localField.options.defaultValue) {
      return { stringVal: localField.options.defaultValue }
    }
  } else if (localField.fieldType === fieldType.number) {
    if (
      localField.options.defaultValue === undefined ||
      localField.options.defaultValue === null ||
      localField.options.defaultValue === ''
    ) {
      return null
    }
    return { stringVal: localField.options.defaultValue }
  } else if (localField.fieldType === fieldType.radio) {
    return convertOptionToDefaultVal(localField)
  } else if (localField.fieldType === fieldType.checkbox) {
    // 多选
    return convertOptionsToDefaultVal(localField)
  } else if (localField.fieldType === fieldType.select) {
    if (localField.options.remote === 1) {
      if (localField.options.multipleFlag) {
        return convertOptionsToDefaultVal(localField)
      }
      const tempObj = convertOptionToDefaultVal(localField)
      if (tempObj) {
        return { optionsVal: [tempObj.optionVal] }
      }
    }
  }
  return null
}

/**
 * 转换单选的默认值
 */
const convertOptionToDefaultVal = (localField) => {
  if (localField.options.defaultValue) {
    const option = localField.options.options.find((opt) => opt.value === localField.options.defaultValue)
    if (option) {
      return { optionVal: { value: option.value, label: option.label } }
    }
  }
  return null
}

/**
 * 转换多选的默认值
 */
const convertOptionsToDefaultVal = (localField) => {
  const tempArr: any = []
  for (const optVal of localField.options.defaultOptions) {
    const option = localField.options.options.find((opt) => opt.value === optVal)
    if (option) {
      tempArr.push({ value: option.value, label: option.label })
    }
  }
  if (tempArr.length > 0) {
    return { optionsVal: tempArr }
  }
  return null
}

// const getJson = () => state.widgetForm

// const setJson = (json: WidgetForm) => {
//   state.widgetForm.list = []
//   merge(state.widgetForm, json)
//   if (json.list.length) {
//     state.widgetFormSelect = json.list[0]
//   }
// }

// const getTemplate = (codeType: CodeType) => generateCode(state.widgetForm, codeType, PlatformType.Antd)

// const clear = () => handleClearable()

/**
 * 业务字段或表单详情数据转换为表单数据
 * @param fieldArr 字段列表
 */
const convertFieldListToShow = (fieldArr) => {
  for (const field of fieldArr) {
    const typeObj = fieldTypeOpstion.find((type) => type.value === field.fieldType)
    if (!typeObj) {
      continue
    }
    const componentObj = antd[typeObj.type].find((item) => item.type === typeObj.code)
    if (!componentObj) {
      continue
    }
    convertFieldToShow(field, componentObj)
  }
}

// 固定组合设置默认字段名称
const setFixLabel = (remoteField, localComponent) => {
  if (localComponent.type === 'fixedCombination') {
    localComponent.options.columns.forEach((item: any, index: number) => {
      item.name = remoteField.combinationChildren?.[index].name || defaultLabels[localComponent.fieldCode][index].label
      item.code = remoteField.combinationChildren?.[index].code || defaultLabels[localComponent.fieldCode][index].code
      item.gridLayoutNumber = remoteField.combinationChildren?.[index].gridLayoutNumber || item.gridLayoutNumber
    })
  }
}

/**
 * 解析表单数据
 * @param remoteField 接口返回数据
 * @param localComponent 本地组件初始化数据
 * TODO：这里未实现循环事件类型的值转换，需要将循环事件内的组件数据转换为表单数据
 *
 */
const convertFieldToShow = (remoteField, localComponent) => {
  const tempItem = cloneDeep(localComponent)
  if (!remoteField.frontId) {
    remoteField.frontId = remoteField.fieldId
  }
  for (const key in remoteField) {
    const fieldAttr = attrs.find((item) => item.remote === key)
    if (!fieldAttr) {
      continue
    }
    if (key === 'dateFormat') {
      setVal(tempItem, fieldAttr.local, getDatePickerFormat(remoteField.dateType, remoteField.dateFormat).value)
    } else if (key === 'defaultVal') {
      const { defaultValue, defaultOptions } = convertDefaultValToShow(remoteField)
      setVal(tempItem, 'options.defaultValue', defaultValue)
      setVal(tempItem, 'options.defaultOptions', defaultOptions)
    } else {
      setVal(tempItem, fieldAttr.local, key === 'requiredFlag' ? !!remoteField[key] : remoteField[key])
    }
  }
  setFixLabel(remoteField, tempItem)
  state.widgetForm.list.push(tempItem)
}

/**
 * 转换默认值格式
 */
const convertDefaultValToShow = (remoteField) => {
  const defaultVal = remoteField.defaultVal
  let defaultValue: any = null
  let defaultOptions = []
  if (!defaultVal) {
    return { defaultValue, defaultOptions }
  }
  if ([fieldType.singleLineText, fieldType.multiLineText].includes(remoteField.fieldType) && defaultVal.stringVal) {
    // 字符串
    defaultValue = defaultVal.stringVal
  } else if (remoteField.fieldType === fieldType.number) {
    if (defaultVal.stringVal === undefined || defaultVal.stringVal === null || defaultVal.stringVal === '') {
      defaultValue = null
    } else {
      defaultValue = Number(defaultVal)
    }
  } else if (remoteField.fieldType === fieldType.radio && defaultVal.optionVal) {
    // 单选
    defaultValue = defaultVal.optionVal.value
  } else if (remoteField.fieldType === fieldType.checkbox && defaultVal.optionsVal) {
    // 多选
    defaultOptions = defaultVal.optionsVal.map((temp) => temp.value)
  } else if (remoteField.fieldType === fieldType.select && defaultVal.optionsVal) {
    const arr = defaultVal.optionsVal.map((temp) => temp.value)
    if (remoteField.multipleFlag) {
      defaultOptions = arr
    } else {
      defaultValue = arr.length > 0 ? arr[0] : null
    }
  } else if (remoteField.fieldType === fieldType.dateTime && defaultVal.stringVal) {
    defaultValue = dayjs(defaultVal.stringVal).format(
      getDatePickerFormat(remoteField.dateType, remoteField.dateFormat).label
    )
  }
  return { defaultValue, defaultOptions }
}

const addField = () => {
  chooseFieldRef.value.show()
}

const onlySubmit = computed(() => {
  if (state.widgetForm?.config?.formClass === 2) {
    // 固定表单只有提交按钮
    return true
  }
  if (props.formBusinessLevel === 1 && props.belongBusinessId === '0') {
    // 运维端
    return false
  }
  if (props.formBusinessLevel === 2) {
    // CTMS的SOP管理
    return false
  }
  return true
})

defineExpose({
  handleSave
})
</script>
